package com.hsy.swu.home.course

import android.annotation.SuppressLint
import android.widget.TextView
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.Ignore
import androidx.room.PrimaryKey
import com.google.gson.annotations.SerializedName
import com.hsy.swu.MyConfig
import java.time.LocalDate
import java.time.LocalTime

@SuppressLint("ClickableViewAccessibility")
@Entity
class CourseModel {
    @SerializedName("XH")
    @ColumnInfo("account")
    var account: String = ""

    @SerializedName("kcmc")
    @ColumnInfo("courseName")
    var courseName: String = ""

    @SerializedName("cdmc")
    @ColumnInfo("classRoom")
    var classRoom: String = ""

    @SerializedName("xm")
    @ColumnInfo("teacher")
    var teacher: String = ""

    @SerializedName("zcd")
    @ColumnInfo("studyWeek")
    var studyWeek: String = ""

    @SerializedName("xqj")
    @ColumnInfo("dayOfWeek")
    var dayOfWeek: Int = 0

    @SerializedName("jcs")
    @ColumnInfo("section")
    var section: String = ""

    @SerializedName("xf")
    @ColumnInfo("credit")
    var credit: Float = 0f

    @SerializedName("kcxz")
    @ColumnInfo("classification")
    var classification: String = ""

    @SerializedName("jxbzc")
    @ColumnInfo("togetherClass")
    var togetherClass: String = ""

    override fun toString() =
        "$account\t$courseName\t$classRoom\t$teacher\t$studyWeek\t$dayOfWeek\t$section\t$credit\t$classification\t$togetherClass"

    @PrimaryKey(autoGenerate = true)
    var id: Int = 0

    @Ignore
    // 持有的 TextView对象
    var tv: TextView? = null

    @delegate:Ignore
    // 起始格数
    val startSection by lazy {
        initStartSection()
    }

    @delegate:Ignore
    val endSection by lazy {
        initEndSection()
    }

    @delegate:Ignore
    // 高度占的格数
    val totalSection by lazy {
        initTotalSection()
    }

    private fun initStartSection(): Int {
        if (section.isEmpty()) return 0
        val sectionDuration = section.split('-')
        return sectionDuration[0].toInt()
    }

    private fun initEndSection(): Int {
        if (section.isEmpty()) return 0
        val sectionDuration = section.split('-')
        return sectionDuration[1].toInt()
    }

    private fun initTotalSection(): Int {
        if (section.isEmpty()) return 0
        val sectionDuration = section.split('-')
        val startSection = sectionDuration[0].toInt()
        val endSection = sectionDuration[1].toInt()
        return endSection - startSection + 1
    }

    /** 本周是否有课 */
    fun isInWeek(currentWeek: Int): Boolean {
        // 在测试中发现，有些开课周写的格式是 “5周,8-9周” 还有些是单独一周的
        // "zcd": "5-7周(单),8-13周", 还有这种？ 数据结构与算法 周一晚上施庆伟那节
        var week: String = studyWeek.replace("周", "") // 先把周字删掉
        // TODO start 可能要改单双周的逻辑
        if (week.contains("(单)")) {
            week = week.replace("(单)", "")
            if (currentWeek % 2 == 0) return false
        }
        if (week.contains("(双)")) {
            week = week.replace("(双)", "")
            if (currentWeek % 2 != 0) return false
        }
        // TODO end
        week.split(',').forEach {
            val isInWeekResult = if (it.contains("-")) {
                currentWeek in it.split("-")[0].toInt()..it.split("-")[1].toInt()
            } else {
                currentWeek == it.toInt()
            }
            if (isInWeekResult) return true
        }
        return false
    }

    /** 是否是上课时间 */
    fun isInCourse(): Boolean {
        val startSection = startSection
        val endSection = endSection
        val startTime = sectionTimeMap[startSection]
        val endTime = sectionTimeMap[endSection]!!.plusMinutes(45)
        return isInWeek(MyConfig.currentWeek)
                && LocalDate.now().dayOfWeek.value == dayOfWeek
                && LocalTime.now().isAfter(startTime) && LocalTime.now().isBefore(endTime)
    }

    companion object {
        val sectionTimeMap = mapOf(
            1 to LocalTime.of(8, 0), 2 to LocalTime.of(8, 55),
            3 to LocalTime.of(10, 0), 4 to LocalTime.of(10, 55),
            5 to LocalTime.of(12, 10), 6 to LocalTime.of(13, 5),
            7 to LocalTime.of(14, 0), 8 to LocalTime.of(14, 55),
            9 to LocalTime.of(15, 50), 10 to LocalTime.of(16, 45),
            11 to LocalTime.of(17, 50), 12 to LocalTime.of(19, 20),
            13 to LocalTime.of(20, 15), 14 to LocalTime.of(21, 10)
        )

        fun nowTimeIsInSection(): Boolean {
            repeat(14) {
                if (LocalTime.now().isAfter(sectionTimeMap[it + 1]) &&
                    LocalTime.now().isBefore(sectionTimeMap[it + 1]!!.plusMinutes(45))
                ) return true
            }
            return false
        }

        fun getCurrentSection(): Int? {
            val currentTime = LocalTime.now()

            // 如果在第一节课前或在最后一节课后则返回-1
            if (currentTime.isBefore(sectionTimeMap[1])
                || currentTime.isAfter(sectionTimeMap[14]!!.plusMinutes(45))
            ) {
                return null
            }

            // 判断当前时间在哪一节课上课时间内
            for (i in 1..14) {
                val endTime = if (i == 14) {
                    sectionTimeMap[14]!!.plusMinutes(45)
                } else {
                    sectionTimeMap[i + 1]
                }
                if (currentTime == sectionTimeMap[i] ||
                    currentTime.isAfter(sectionTimeMap[i])
                    && currentTime.isBefore(endTime)
                ) {
                    return i
                }
            }

            return null
        }

        fun getCurrentCourse(courseList: List<CourseModel>): CourseModel? {
            courseList.forEach {
                if (it.isInCourse()) return it
            }
            return null
        }
    }
}